package mynl

import (
	"fmt"
	"strings"
)

/////////////////////////////////////////////////////////////////////////
// 解释器

/**
 * 遍历AST，执行函数调用。
 */
type Intepretor struct {
	AstVisitor
}

func NewIntepretor() *Intepretor {
	return &Intepretor{}
}

func (selfx *Intepretor) VisitProg(prog *Prog) int {
	var retVal int

	//执行所有的函数调用
	for i := range prog.Stmts {
		//根据stmt的类型，进行不同的处理
		switch v := prog.Stmts[i].(type) {
		case *FunctionCall:
			retVal = selfx.runFunction(v)
		default:
		}
	}
	return retVal
}

//执行一个函数体
func (selfx *Intepretor) visitFunctionBody(functionBody *FunctionBody) int {
	var retVal int

	//依次执行每条函数调用
	for i := range functionBody.Stmts {
		retVal = selfx.runFunction(&functionBody.Stmts[i])
	}

	return retVal
}

//执行一个函数
func (selfx *Intepretor) runFunction(functionCall *FunctionCall) int {
	if strings.HasPrefix(functionCall.Name, "nl.") {
		//内置函数
		if strings.HasPrefix(functionCall.Name, "nl.println") {
			if len(functionCall.Parameters) > 0 {
				fmt.Println(functionCall.Parameters[0])
			} else {
				fmt.Println()
			}
			return 0
		}
	} else {
		//自定义函数
		//找到函数定义，继续遍历函数体
		if functionCall.Definition != nil {
			selfx.visitFunctionBody(&functionCall.Definition.Body)
		} else {
			fmt.Println(functionCall.Name + " not found!!!")
		}
	}
	return 0
}
